回到前端部分,在 api 中新增 login 及 register

createAsyncThunk接著新增 accountSlice.js
login 及 register ,然後使用 createAsyncThunk 來處理非同步函數

extraReducers

extraReducers 用來處理 createAsyncThunk 建立的非同步函數,可以分為三個階段:pending, fulfilled, rejected ,依照字面上的意思很好理解,我們可以分別定義在各自的階段需要執行什麼任務,例如 status 的狀態以及是否成功註冊或登入的 login.hasLogin 布林值判斷

Login.js 及 Register.js接下來調整登入及註冊頁面的功能:
loginAsync ,並在 handleLogin 中搭配 dispatch 使用useSelector ,取出全域變數 account.status 以及 account.user ,並使用 useEffect 來判斷 loginAsync 的執行階段useNavigate ,如果登入成功的話,將畫面跳轉至首頁 → navigate('/')
import React, { useState, useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { EnvelopeIcon, LockClosedIcon } from '@heroicons/react/24/solid';
import Header from '../components/Header';
import Footer from '../components/Footer';
import { loginAsync } from '../redux/accountSlice';
export default function Login() {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const navigate = useNavigate();
    const loginStatus = useSelector((state) => state.account.status);
    const user = useSelector((state) => state.account.user);
    const dispatch = useDispatch();
    const handleLogin = async () => {
        dispatch(loginAsync({ email, password }));
    };
    useEffect(() => {
        if (loginStatus === 'idle' && user.name) {
            alert('登入成功!');
            navigate('/');
        }
    }, [loginStatus]);
		...
}
Register.js 也是相同的概念~

Header.js取得全域變數 account.login.hasLogin 以及 account.user ,並使用 hasLogin 來判斷使用者是否已登入來改變 header 的顯示 → {hasLogin ? <></> : <></>}
import { useSelector } from 'react-redux';
const { hasLogin } = useSelector((state) => state.account.login);
const { name, photo } = useSelector((state) => state.account.user);
{hasLogin ? (
    <>
        <Link
            to={'/add-post'}
            className="flex mx-5 text-white font-medium px-4 py-2 bg-yellow-700/40 hover:bg-yellow-700/70 rounded-md"
        >
            <PencilIcon className="h-6 w-6 mr-2" />
            寫點東西
        </Link>
        <Link to={'/'} className="flex mx-5 hover:text-yellow-700 align-middle">
            {photo ? (
                <img className="w-9 h-9 rounded-full" src={photo} alt="avatar" />
            ) : (
                <div className="w-9 h-9 rounded-full bg-yellow-700/70" />
            )}
            <span className="font-medium ml-4 my-auto">Hi, {name}</span>
        </Link>
    </>
) : (
    <Link
        to={'/login'}
        className="flex mx-5 text-white font-medium px-4 py-2 bg-yellow-700/40 hover:bg-yellow-700/70 rounded-md"
    >
        登入 / 註冊
    </Link>
)}
AddPost.js取得全域變數 account.user 中的 name ,然後傳給 createPost api
import { useSelector } from 'react-redux';
const author = useSelector((state) => state.account.user.name);
const handleAddPost = async () => {
    const res = await createPost({ title, author, image, content });
    console.log(res.data);
    setTitle('');
    setImage('');
    setContent('');
};
目前的畫面及功能呈現

這樣就大致完成了註冊 / 登入的功能啦~ 當然還有很多細節需要調整及修改,如果後續有機會再來調整!